# -*- coding: utf-8 -*-
# @Time: 2021/9/28 16:55
# @Author: yh
# @Remark: 视频概览Server层
import datetime
import logging
import time

from mxsoftpy import Server

from db.common.VideoManage.VideoQuality.conf import TestItemsDB
from db.common.VideoManage.VideoQuality.video import VideoDB
from db.common.VideoManage.VideoQuality.video_group import VideoGroupDB
from db.common.VideoManage.VideoQuality.inspection_record import InspectionRecordDB
from db.common.VideoManage.VideoQuality.video_overview import VideoOverviewDB
from utils.public.data_process import round_to_100_percent
from utils.public.time_process import TimeProcess


class VideoOverviewServer(Server):
    __db__ = VideoOverviewDB

    @staticmethod
    def device_overview() -> dict:
        """
        设备概览
        """
        videos = VideoDB().simple_list()
        ware_videos = VideoDB().simple_list(repair_state=1)
        normal_num = 0  # 正常设备数量
        fault_num = 0  # 故障设备数量
        fault_today_num = 0  # 今日新增故障设备数量
        ware_num = len(ware_videos)  # 待修数量
        for k, v in videos.items():
            if v['running_error'] or v['running_fail'] or v['running_normal']:
                if not v['running_error'] and not v['running_fail']:
                    normal_num += 1
                elif v['running_time'] >= int(time.mktime(datetime.date.today().timetuple())) and v['running_error']:
                    fault_num += 1
                    fault_today_num += 1
                elif v['running_error']:
                    fault_num += 1

        return {'normal_num': normal_num, 'fault_num': fault_num, 'fault_today_num': fault_today_num,
                'ware_num': ware_num}

    @staticmethod
    def fault_device_type() -> dict:
        """
        故障类型占比
        """
        videos = VideoDB().simple_list(running_error__ne='')
        test_items = TestItemsDB('TestItems').use_keys([])  # 所有检测项目
        error_data = {i: 0 for i in test_items}
        for video_code, value in videos.items():
            for i in value['running_error'].split(';') if value['running_error'] else []:
                if test_items.get(i):
                    error_data[i] += 1
                else:
                    logging.error('校验视频code：%s的running_error列表时，发现停用或不存在的检测项目code：%s' % (video_code, i))
        per_dict = round_to_100_percent(list(error_data.values()))
        data_list = [{'code': key, 'name': test_items[str(key)]['name'], 'num': error_data[key], 'percent': per_dict[index + 1]}
                     for index, key in enumerate(error_data)]
        res_dict = {
            "data": data_list,
            "total": len(data_list)
        }
        return res_dict

    @staticmethod
    def fault_trend_week() -> list:
        """
        本周故障设备趋势
        """
        today = time.time()
        week_list = TimeProcess().get_week(today)
        horizon = TimeProcess().stamp_horizon(today)
        every_day_list = TimeProcess().get_every_day(today)
        records = InspectionRecordDB().select(select_data={'test_state': 3, 'MXTIME__between': horizon})
        res = {}
        # 0-6 对应星期一至星期天
        for i in range(7):
            err_sd_list = []  # 当天出现故障的设备列表
            res[week_list[i]] = 0  # 当天的故障设备数
            for record in records:
                # 判断属于一周之内具体哪一天
                if every_day_list[i][1] >= record['test_time'] >= every_day_list[i][0]:
                    if record['video_code'] not in err_sd_list:
                        err_sd_list.append(record['video_code'])
                        res[week_list[i]] += 1

        return [{"date": k, "fault_num": v} for k, v in res.items()]

    @staticmethod
    def fault_device_statistic() -> dict:
        """
        故障设备按组统计
        """
        group_dict = VideoGroupDB().group_dict()  # 设备组
        videos = VideoDB().simple_list(running_error__ne='')
        res_list = []
        for k, v in group_dict.items():
            res = {
                'fault_device_count': 0,
                'code': k,
                'name': v.get('name'),
                 }

            for video in videos.values():
                if video['group_code'] == k:
                    res['fault_device_count'] += 1
            res_list.append(res)
        res_dict = {
                    'data': res_list,
                    'total': len(res_list)    # 总条数
                    }
        return res_dict

    @staticmethod
    def fault_type_statistic() -> dict:
        """
        故障类型统计
        上周周日数据与当前数据对比
        """

        today = time.time()
        last_week_day = today - 86400*7
        last_horizon = TimeProcess().stamp_horizon(last_week_day)  # 上周时间戳范围
        last_records = InspectionRecordDB().select(select_data={'MXTIME__between': last_horizon})
        test_items_dict = TestItemsDB('TestItems').use_keys(['name'])
        fault_type_list = []
        videos = VideoDB().simple_list(running_error__ne='')
        last_test_list = []  # 上周测试数据列表
        last_stamp = 0
        if last_records:
            # 拿到上周最后一次测试的测试数据
            for record in last_records:
                if record['test_time'] > last_stamp:
                    last_stamp = record['test_time']
                    last_test_list = [record]
                elif record['test_time'] == last_stamp:
                    last_test_list.append(record)

        #  根据测试类型遍历
        for k, v in test_items_dict.items():
            res = {
                   "test_code": k,
                   "this_fault_num": 0,
                   "last_fault_num": 0,
                   "fault_name": v['name']
                   }

            #  当前数据类型统计
            for video in videos.values():
                for i in video['running_error'].split(';'):
                    if i == k:
                        res["this_fault_num"] += 1

            # 上周最后一次数据故障类型统计
            for last_test in last_test_list:
                if str(k) == last_test.get('test_code'):
                    if last_test.get('test_state') == 3:
                        res["last_fault_num"] += 1

            fault_type_list.append(res)

        res_dict = {
            "data": fault_type_list,
            "total": len(fault_type_list)
        }
        return res_dict

